package com.droiddata;

import java.util.ArrayList;
import java.util.List;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class SimpleQueryTransactionCallback<T> implements ITransactionCallback<List<T>> {
	private boolean distinct;
	private String table;
	private String[] columns;
	private String selection;
	private String[] selectionArgs;
	private String groupBy;
	private String having;
	private String orderBy;
	private String limit;
	
	private ICursorMapper<T> cursorMapper;
	
	/**
	 * Selects all rows in the table
	 * @param table
	 * @param columns
	 */
	public SimpleQueryTransactionCallback(String table, String[] columns, ICursorMapper<T> cursorMapper) {
		this(false, table, columns, null, null, null, null, null, null, cursorMapper);
	}
	
	/**
	 * Selects all rows in the table matching a WHERE clause
	 * @param table
	 * @param columns
	 * @param selection
	 * @param selectionArgs
	 */
	public SimpleQueryTransactionCallback(String table, String[] columns, String selection, String[] selectionArgs, ICursorMapper<T> cursorMapper) {
		this(false, table, columns, selection, selectionArgs, null, null, null, null, cursorMapper);
	}
	
	public SimpleQueryTransactionCallback(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, ICursorMapper<T> cursorMapper) {
		this(false, table, columns, selection, selectionArgs, groupBy, having, orderBy, null, cursorMapper);
	}
	
	public SimpleQueryTransactionCallback(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, ICursorMapper<T> cursorMapper) {
		this(false, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit, cursorMapper);
	}
	
	public SimpleQueryTransactionCallback(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, ICursorMapper<T> cursorMapper) {
		this.cursorMapper = cursorMapper;
		if(cursorMapper == null) {
			throw new IllegalArgumentException("A cursor mapper must be provided to the SimpleQueryTransactionCallback");
		}		
		
		this.distinct = distinct;
		this.table = table;
		this.columns = columns;
		this.selection = selection;
		this.selectionArgs = selectionArgs;
		this.groupBy = groupBy;
		this.having = having;
		this.orderBy = orderBy;
		this.limit = limit;
	}

	@Override
	public final List<T> doInTransaction(SQLiteDatabase db, ITransactionStatus status) {
		List<T> mappedResults = new ArrayList<T>();
		
		Cursor result = null;
		try {
			result = db.query(distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);			
			result.moveToFirst();			
			while(!result.isAfterLast()) {
				T mapped = cursorMapper.map(result);
				if(mapped != null)
					mappedResults.add(mapped);
			    result.moveToNext();
			}
		}
		catch(Exception e) {
			Log.e("SimpleQueryTransactionCallback: Failed to perform query: ", (e.getMessage() == null) ? "no specifics available" : e.getMessage());
			e.printStackTrace();
		}
		finally {
			if(result != null)
				result.close();
		}
		
		return mappedResults;	
	}
}
